#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <algorithm>
#include <string>
#include <list>
#include <iterator>
#include <utility>
#include <unordered_map>

using namespace std;

void pr_11_3()
{
    map<string, size_t> word_count;  // 一个 string 到 size_t 的映射
    string word;
    while (cin >> word) {  // 获取输入
        ++word_count[word];  // 这个单词出现的次数加 1
    }
    for (const auto &w : word_count) {  // 对于 map 中的每个元素
        // 打印结果
        cout << w.first << " 出现了 " << w.second << " 次." << endl;
    }
}

string &trans(string &s)
{
    for (string::size_type p = 0; p < s.size(); p++) {
        if (s[p] >= 'A' && s[p] <= 'Z') {
            s[p] -= ('A' - 'a');
        } else if (s[p] == ',' || s[p] == '.') {
            s.erase(p, 1);
        }
    }
    return s;
}

void pr_11_4()
{
    map<string, size_t> word_count;  // string 到 size_t 的映射
    string word;
    while (cin >> word) {
        ++word_count[trans(word)];
    }
    for (const auto &w : word_count) {
        cout << w.first << " 出现了 " << w.second << " 次." << endl;
    }
}

void AddFamily(map<string, vector<string>> &families, const string &family)
{
    if (families.find(family) == families.end()) {
        // 如果查询的家庭不在 map 中,则创建一个
        families[family] = vector<string>();
    }
}

void AddChild(map<string, vector<string>> &families, const string &family,
              const string &child)
{
    families[family].push_back(child);
}

void pr_11_7()
{
    map<string, vector<string>> families;  // 表示家庭的 map
    AddFamily(families, "张");
    AddChild(families, "张", "强");
    AddChild(families, "张", "刚");
    AddChild(families, "王", "五");
//    AddFamily(families, "王");  // 这个可以省略，如果遇到不在 map 中的关键字，会自动添加
    for (auto &f : families) {
        cout << f.first << "家的孩子：" ;
        for (auto &c : f.second) {
            cout << c << " ";
        }
        cout << endl;
    }
}

void pr_11_8()
{
    vector<string> unique_word;  // 不重复的单词
    string word;
    while (cin >> word) {
        trans(word);
        if (find(unique_word.begin(), unique_word.end(), word)
                == unique_word.end()) {
            unique_word.push_back(word);  // 添加不重复单词
        }
    }
    for (const auto &w : unique_word) {
        // 打印不重复单词
        cout << w << " ";
    }
    cout << endl;
}

void pr_11_9()
{
    map<string, list<int>> word_lineno;  // 单词到行号的映射
    string line;
    string word;
    int lineno = 0;
    while (getline(cin, line)) {
        lineno++;
        istringstream l_in(line);  // 构造字符串流，读取单词
        while (l_in >> word) {
            trans(word);
            word_lineno[word].push_back(lineno);  // 添加行号
        }
    }
    for (const auto &w : word_lineno) {
        cout << w.first << " 所在行： ";
        for (const auto &i : w.second) {
            cout << i << " ";
        }
        cout << endl;
    }
}

void pr_11_12()
{
    vector<pair<string, int>> data;
    string s;
    int v;
    while (cin >> s && cin >> v) {
        // 下面三种添加方式都可以,选择一种即可
        data.push_back(make_pair(s, v));
        data.push_back(pair<string, int>(s, v));
        data.push_back({s, v});
    }
    for (const auto &p : data) {
        cout << p.first << " " << p.second << endl;
    }
}

void AddFamily(map<string, vector<pair<string, string>>> &families,
               const string &family)
{
    families[family];
}

void AddChild(map<string, vector<pair<string, string>>> &families,
              const string &family, const string &child, const string &birthday)
{
    families[family].push_back({child, birthday});
}

void pr_11_13()
{
    map<string, vector<pair<string, string>>> families;
    AddChild(families, "张", "强", "1970-01-01");
    AddChild(families, "张", "刚", "1980-01-01");
    AddChild(families, "王", "五", "1990-01-01");
    for (const auto &f : families) {
        cout << f.first << "家的孩子： ";
        for (const auto &p : f.second) {
            cout << p.first << " " << p.second << " ";
        }
        cout << endl;
    }
}

void pr_11_16()
{
    map<int, int> m;
    auto map_it = m.begin();
    map_it->second = 0;
}

void pr_11_20()
{
    map<string, size_t> word_count;
    string word;
    while (cin >> word) {
        auto ret = word_count.insert({word, 1});
        if (!ret.second) {
            ++ret.first->second;
        }
    }
    for (const auto &w : word_count) {
        cout << w.first << " " << w.second << endl;
    }
}

void pr_11_22()
{
    map<string, vector<int>> m;
    string word;
}

void AddChild(multimap<string, string> &families, const string &family,
              const string &child)
{
    families.insert({family, child});
}

void pr_11_23()
{
    multimap<string, string> families;
    AddChild(families, "张", "强");
    AddChild(families, "张", "刚");
    AddChild(families, "王", "五");

    for (const auto &f : families) {
        cout << f.first << " " << f.second << " " << endl;
    }
}

void pr_11_28()
{
    map<string, vector<int>> m;
    map<string, vector<int>>::iterator i = m.find(0);
}

void RemoveAuthor(multimap<string, string> &books, const string &author)
{
    auto pos = books.equal_range(author);  // 查找给定作者范围
    if (pos.first == pos.second) {  // 如果没有查找到
        cout << "没有" << author << "这个作者" << endl << endl;
    } else {
        books.erase(pos.first, pos.second);  // 删除该作者所有著作
    }
}

void PrintBooks(multimap<string, string> &books)
{
    cout << "当前数目包括： " << endl;
    for (auto &book : books) {
        cout << book.first << ", << " << book.second << ">>" << endl;
    }
    cout << endl;
}

void pr_11_31()
{
    multimap<string, string> books;
    books.insert({"Barth,John", "Sot-Weed Factor"});
    books.insert(make_pair("Barth,John", "Lost in the Funhouse"));
    books.insert(pair<string, string>("金庸", "射雕英雄传"));
    books.insert(pair<string, string>("金庸", "天龙八部"));

    PrintBooks(books);
    RemoveAuthor(books, "张三");
    PrintBooks(books);
    RemoveAuthor(books, "金庸");
    PrintBooks(books);
}

void pr_11_38_1()
{
    unordered_map<string, size_t> word_count;
    string word;
    while (cin >> word) {
        ++word_count[word];
    }
    for (const auto &w : word_count) {
        cout << w.first << " 这个单词出现 " << w.second << " 次";
    }
}

unordered_map<string, string> BuildMap(ifstream &map_file)
{
    unordered_map<string, string> trans_map;
    string key, value;
    while (map_file >> key && getline(map_file, value)) {
        if (value.size() > 1) {
            trans_map[key] = value.substr(1);
        } else {
            throw runtime_error("no rule for " + key);
        }
    }
    return trans_map;
}

const string &Transform(const string &s, const unordered_map<string, string> &m)
{
    auto ret = m.find(s);
    if (ret != m.end()) {
        return ret->second;
    } else {
        return s;
    }
}

void WordTransform(ifstream &map_file, ifstream &input_file)
{
    auto trans_map = BuildMap(map_file);
    string text;
    while (getline(input_file, text)) {
        istringstream stream(text);
        string word;
        bool first = true;
        while (stream >> word) {
            if (first == true) {
                first = false;
            } else {
                cout << " ";
            }
            cout << Transform(word, trans_map);
        }
        cout << endl;
    }
}

int main()
{
    pr_11_13();
    return 0;
}
